#include	<time.h>
#include	<stdio.h>
#include	<strings.h>
#include	<string.h>
#include	<stdlib.h>
#include 	<sys/socket.h>
#include 	<netinet/in.h>

#define MAXLINE		256
#define	PORTA_SERVIDOR	13
#define LISTENQ		1024
#define	SA		struct sockaddr
#define	SAIN		struct sockaddr_in

//Prototipos de funcoes
int sockfd_to_family(int);

int
main(int argc, char **argv)
{
	int				listenfd, connfd;
	SAIN				servaddr, cliaddr;
	char				buff[MAXLINE];
	time_t				ticks;
	socklen_t			len;
	pid_t				pid;

	listenfd = socket(AF_INET, SOCK_STREAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family      = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port        = htons(PORTA_SERVIDOR);	

	printf ("Servidor entrando no ar na porta %d ... \n", PORTA_SERVIDOR);

	bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

	listen(listenfd, LISTENQ);

	for ( ; ; ) {
	
		len = sizeof(cliaddr);

		connfd = accept(listenfd, (SA *) &cliaddr, &len);

		if ( (pid = fork()) == 0 ) {

			close (listenfd); // filho fecha o socket ouvinte

			printf ("Conexão do cliente %s, porta %d\n", 
				inet_ntop (AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
				ntohs(cliaddr.sin_port));

			ticks = time(NULL);
			snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
			write(connfd, buff, strlen(buff));
			close(connfd); // filho fecha o socket de conexão
			exit(0); //filho termina
		}
		printf ("Familia e endereco de protocolo: %d\n", sockfd_to_family(connfd));
		close(connfd); //pai fecha socket de conexão

	}
}


int sockfd_to_family(int sockfd) {

	struct sockaddr_storage ss;
	socklen_t 	len;

	len = sizeof(ss);
	if (getsockname (sockfd, (SA *) &ss, &len) < 0)
		return(-1);
	return (ss.ss_family);

}
